/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package travelingsalesman;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.JPanel;

/**
 *
 * @author Geost1gma
 * @author DiaAWAY
 */
public class Graph extends JPanel {

    int xSize = 500;
    int ySize = 500;
    int cityDiameter = 3;
    int[][] cities = null;
    int[][] nodes = null;
    private Queue<int[][]> queue = new LinkedList<int[][]>();
    private double updateInterval = 10; // how often should the graph use new data, in milliseconds
    private double startTime;
    private double currentTime;
    public boolean isPausing = false;
    int count = 0;
    int totalCount = 0;

    public Graph() {
        setSize(xSize, ySize);
        setVisible(true);
        startTime = System.currentTimeMillis();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = ((Graphics2D) g);
        AffineTransform at = g2.getTransform();
        AffineTransform oldAt = g2.getTransform();

        at.translate(25, 25);
        at.scale(0.9, 0.9);
        at.translate(xSize/2, ySize/2);
        at.scale(-1, 1);
        at.rotate(Math.toRadians(-90.0));
        at.translate(-xSize/2, -ySize/2);

        g2.setTransform(at);
        if (cities != null) {
            g.setColor(Color.blue);
            for (int i = 0; i < cities.length; i++) {
                g.drawOval(
                        (int) (cities[i][0] - (cityDiameter / 2)), // adjust where to draw, since drawOval draws in top left corner.
                        (int) (cities[i][1] - (cityDiameter / 2)), // adjust where to draw, since drawOval draws in top left corner.
                        cityDiameter, cityDiameter);
            }
        }
        currentTime = System.currentTimeMillis();
        if (!isPausing && (currentTime - startTime > updateInterval)) {
            startTime = currentTime;
            if (count < totalCount) count++;
            // DRAW RING/NETWORK8/ETC
            if (queue.peek() != null) {
//                System.out.println("GRAPH: CONVERTING ARRAY IN QUEUE TO LOCAL AND SETTING NODE. ITEMS IN QUEUE: " + queue.size());
                nodes = queue.poll();
            }
        }
        if (nodes != null) {
            g.setColor(Color.BLACK);
            int length = nodes.length;
            for (int i = 0; i < length - 1; i++) {
                g.drawLine(nodes[i][0], nodes[i][1], nodes[i + 1][0], nodes[i + 1][1]);
            }
            g.drawLine(nodes[length - 1][0], nodes[length - 1][1], nodes[0][0], nodes[0][1]);
        }
        g2.setTransform(oldAt);
        g.drawString(""+count+" / "+totalCount, 10, 15);
        
    }

    public int getxSize() {
        return xSize;
    }

    public void setxSize(int xSize) {
        this.xSize = xSize;
    }

    public int getySize() {
        return ySize;
    }

    public void setySize(int ySize) {
        this.ySize = ySize;
    }

    public void setCities(double[][] globalCities) {
        this.cities = globalToLocal(globalCities);
    }

    public void addWeights(double[][] w) {
        queue.offer(globalToLocal(w));
    }

    /**
     * Converts global coords to local, assumes global coords from 0 to 1
     * @param global
     * @return
     */
    private int[][] globalToLocal(double[][] global) {
        if (global != null) {
            int[][] local = new int[global.length][global[0].length];
            for (int i = 0; i < global.length; i++) {
                local[i][0] = (int) (global[i][0] * xSize); // scale it down, translate it
                local[i][1] = (int) (global[i][1] * ySize); // scale it down, translate it
//                local[i][0] = (int) ((global[i][0] * (xSize*0.9)) + (xSize*0.05)); // scale it down, translate it
//                local[i][1] = (int) ((global[i][1] * (ySize*0.9)) + (ySize*0.05)); // scale it down, translate it
//                System.out.println("global["+i+"][0]:" + global[i][1] + ", global["+i+"][1]:" + global[i][1]
//                        + "local[0][" + i + "]:" + local[0][i] + ", local[1][" + i + "]:" + local[1][i]);
            }
            return local;
        }
        return null;
    }

    protected void stop() {
        count = 0;
        queue.clear();
    }

    protected void updateMaxCount(int maxCount) {
        totalCount = maxCount;
    }
}
